bitkeeper revision 1.1559 (4294fab4CMjRyJfuEBP1lUbAC6G9GA)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 25 May 2005 22:22:44 +0000 (22:22 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 25 May 2005 22:22:44 +0000 (22:22 +0000)
- pygrub/README provides information on packages needed to compile pygrub
- support reiserfs {2,3} filesystem
- dynamically build modules based on which filesystem libraries the
system has (proposed by Jeremy)
- pump up pygrub to version 0.2

Signed-off-by: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
.rootkeys
tools/pygrub/README
tools/pygrub/setup.py
tools/pygrub/src/fsys/reiser/__init__.py [new file with mode: 0644]
tools/pygrub/src/fsys/reiser/reisermodule.c [new file with mode: 0644]

index 93567d5df2faff21c4d7ac59368c14de436b94ff..0a86cf84079686b99bf623e1564beecaeeb9bb5e 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 4270cc81RTIiq9si0dI4YRTRE4KRMw tools/pygrub/src/fsys/ext2/__init__.py
 4270cc81YCYa4pexivBD2NdLE2F_Pg tools/pygrub/src/fsys/ext2/ext2module.c
 4270cc81o4BL5e8Cs87aSi8EXA5NtQ tools/pygrub/src/fsys/ext2/test.py
+4294fab3_A8gB1E3T-8fDt0x0eGRqw tools/pygrub/src/fsys/reiser/__init__.py
+4294fab3On_kRmhm1lwm4SDteFP_7Q tools/pygrub/src/fsys/reiser/reisermodule.c
 4270cc81TS6L_tEO6wSp5wcURcpldQ tools/pygrub/src/pygrub
 40c9c468icGyC5RAF1bRKsCXPDCvsA tools/python/Makefile
 40ffc44dOwe1CcYXGCkYHdG_NxcccA tools/python/logging/logging-0.4.9.2/PKG-INFO
index f186fdae9fee06324688226ba4a59d251bc810f5..b58c1b96a84c8f3a040d925b5bfa0f754ad65ae3 100644 (file)
@@ -1 +1,15 @@
-Compiling this needs RPM e2fsprogs-devel installed.
\ No newline at end of file
+pygrub is a grub-like bootloader for xen. This tool is to use to boot domU images.
+
+To compile pygrub, you will need the following packages installed:
+
+1) Libraries of ext2fs, which is the following package (depend on your Linux distribution):
+       - e2fslibs-dev on Debian based distributions (Debian, Ubuntu, Linspire, Libranet, Xandros, etc...)
+       - e2fsprogs-devel on RedHat, Fedora Core
+       - libext2fs2-devel on Mandriva/Mandrake
+       - e2fsprogs on Gentoo
+
+2) Libraries of reiserfs, which is the following package (depend on your Linux distribution):
+       - libreiserfs-dev on Debian based distributions (Debian, Ubuntu, Xandros, Libranet, Xandros, etc...)
+       - progsreiserfs-devel on RedHat
+       - progreiserfs on Gentoo
+
index 193c160a3b6343bdb7a3e182ffbdbf56a94e9aa7..b72ea38857bdfe4ce1da30824e243ab2a963562a 100644 (file)
@@ -3,14 +3,27 @@ import os
 
 extra_compile_args  = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
 
-# in a perfect world, we'd figure out the fsys modules dynamically
-ext2 = Extension("grub.fsys.ext2._pyext2",
-                 extra_compile_args = extra_compile_args,
-                 libraries = ["ext2fs"],
-                 sources = ["src/fsys/ext2/ext2module.c"])
+fsys_mods = []
+fsys_pkgs = []
+
+if os.path.exists("/usr/include/ext2fs/ext2_fs.h"):
+    ext2 = Extension("grub.fsys.ext2._pyext2",
+                     extra_compile_args = extra_compile_args,
+                     libraries = ["ext2fs"],
+                     sources = ["src/fsys/ext2/ext2module.c"])
+    fsys_mods.append(ext2)
+    fsys_pkgs.append("grub.fsys.ext2")
+
+if os.path.exists("/usr/include/reiserfs/reiserfs.h"):
+    reiser = Extension("grub.fsys.reiser._pyreiser",
+                     extra_compile_args = extra_compile_args,
+                     libraries = ["reiserfs"],
+                     sources = ["src/fsys/reiser/reisermodule.c"])
+    fsys_mods.append(reiser)
+    fsys_pkgs.append("grub.fsys.reiser")
 
 setup(name='pygrub',
-      version='0.1',
+      version='0.2',
       description='Boot loader that looks a lot like grub for Xen',
       author='Jeremy Katz',
       author_email='katzj@redhat.com',
@@ -18,8 +31,7 @@ setup(name='pygrub',
       package_dir={'grub': 'src'},
       scripts = ["src/pygrub"],
       packages=['grub',
-                'grub.fsys',
-                'grub.fsys.ext2'],
-      ext_modules = [ext2]
+                'grub.fsys'].extend(fsys_pkgs),
+      ext_modules = fsys_mods
       )
                
diff --git a/tools/pygrub/src/fsys/reiser/__init__.py b/tools/pygrub/src/fsys/reiser/__init__.py
new file mode 100644 (file)
index 0000000..e49e7c3
--- /dev/null
@@ -0,0 +1,39 @@
+# 
+# Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+from grub.fsys import register_fstype, FileSystemType
+from _pyreiser import *
+
+import os
+
+FSMAGIC2 = 'ReIsEr2'
+FSMAGIC3 = 'ReIsEr3'
+
+class ReiserFileSystemType(FileSystemType):
+    def __init__(self):
+        FileSystemType.__init__(self)
+        self.name = "reiser"
+
+    def sniff_magic(self, fn, offset = 0):
+        fd = os.open(fn, os.O_RDONLY)
+        os.lseek(fd, 0x10000, 0)
+        buf = os.read(fd, 0x40)
+        if len(buf) == 0x40 and (buf[0x34:0x3B] in [FSMAGIC2, FSMAGIC3]) :
+            return True
+        return False
+
+    def open_fs(self, fn, offset = 0):
+        if not self.sniff_magic(fn, offset):
+            raise ValueError, "Not a reiserfs filesystem"
+        return ReiserFs(fn)
+
+register_fstype(ReiserFileSystemType())
+
diff --git a/tools/pygrub/src/fsys/reiser/reisermodule.c b/tools/pygrub/src/fsys/reiser/reisermodule.c
new file mode 100644 (file)
index 0000000..dea7152
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * reisermodule.c - simple python binding for libreiserfs{2,3}
+ *
+ * Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * general public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <Python.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dal/file_dal.h>
+#include <reiserfs/reiserfs.h>
+
+#if (PYTHON_API_VERSION >= 1011)
+#define PY_PAD 0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L
+#else
+#define PY_PAD 0L,0L,0L,0L
+#endif
+
+
+/* global error object */
+PyObject *ReiserError;
+
+typedef struct {
+    PyObject_HEAD
+    reiserfs_fs_t *fs;
+       dal_t *dal;
+} ReiserFs;
+
+typedef struct _ReiserFile ReiserFile;
+struct _ReiserFile {
+    PyObject_HEAD
+    reiserfs_file_t *file;
+};
+
+void file_dal_close(dal_t *dal) {
+
+       if (!dal) return;
+
+       close((int)dal->dev);
+       dal_free(dal);
+}
+
+/* reiser file object */
+
+static PyObject *
+reiser_file_close (ReiserFile *file, PyObject *args)
+{
+    if (file->file != NULL)
+       {
+        reiserfs_file_close(file->file);
+               file->file = NULL;
+       }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+reiser_file_read (ReiserFile *file, PyObject *args)
+{
+    int size = 0;
+    size_t n, total = 0;
+    PyObject * buffer = NULL;
+
+    if (file->file == NULL) {
+        PyErr_SetString(PyExc_ValueError, "Cannot read from closed file");
+        return NULL;
+    }
+
+    if (!PyArg_ParseTuple(args, "|i", &size))
+        return NULL;
+
+    buffer = PyString_FromStringAndSize((char *) NULL, (size) ? size : 4096);
+    if (buffer == NULL)
+        return buffer;
+    while (1) {
+        n = reiserfs_file_read(file->file, PyString_AS_STRING(buffer) + total, 
+                               (size) ? size : 4096);
+        if (n == 0)
+            break;
+
+        total += n;
+
+        if (size && size == total)
+            break;
+
+        if (!size) {
+            _PyString_Resize(&buffer, total + 4096);
+        }
+    }
+
+    _PyString_Resize(&buffer, total);
+    return buffer;
+}
+
+static void
+reiser_file_dealloc (ReiserFile * file)
+{
+    if (file->file != NULL) {
+        reiserfs_file_close(file->file);
+               file->file = NULL;
+       }
+       PyObject_DEL(file);
+}
+
+static struct PyMethodDef ReiserFileMethods[] = {
+       { "close", (PyCFunction) reiser_file_close, METH_VARARGS, NULL },
+       { "read", (PyCFunction) reiser_file_read, METH_VARARGS, NULL },
+       { NULL, NULL, 0, NULL } 
+};
+
+static PyObject *
+reiser_file_getattr (ReiserFile * file, char * name)
+{
+       return Py_FindMethod (ReiserFileMethods, (PyObject *) file, name);
+}
+
+static char ReiserFileType__doc__[] = "This is the reiser filesystem object";
+PyTypeObject ReiserFileType = {
+       PyObject_HEAD_INIT(&PyType_Type)
+       0,                              /* ob_size */
+       "ReiserFile",                   /* tp_name */
+       sizeof(ReiserFile),             /* tp_size */
+       0,                              /* tp_itemsize */
+       (destructor) reiser_file_dealloc,       /* tp_dealloc */
+       0,                              /* tp_print */
+       (getattrfunc) reiser_file_getattr,      /* tp_getattr */
+       0,                              /* tp_setattr */
+       0,                              /* tp_compare */
+       0,                              /* tp_repr */
+       0,                              /* tp_as_number */
+       0,                              /* tp_as_sequence */
+       0,                              /* tp_as_mapping */
+       0,              /* tp_hash */
+       0,              /* tp_call */
+       0,              /* tp_str */
+       0,                              /* tp_getattro */
+       0,                              /* tp_setattro */
+       0,                              /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+       ReiserFileType__doc__,
+       PY_PAD
+};
+
+static PyObject *
+reiser_file_open (ReiserFs *fs, char *name, int flags)
+{
+    ReiserFile *file;
+    reiserfs_file_t *f;
+
+    file = (ReiserFile *) PyObject_NEW(ReiserFile, &ReiserFileType);
+
+    f = reiserfs_file_open(fs->fs, name, flags);
+    file->file = f;
+    
+    if (!f) {
+        PyErr_SetString(PyExc_ValueError, "unable to open file");
+        return NULL;
+    }
+
+    return (PyObject *) file;
+}
+
+static PyObject *
+reiser_file_exist (ReiserFs *fs, char *name)
+{
+    reiserfs_file_t *f;
+
+    f = reiserfs_file_open(fs->fs, name, O_RDONLY);
+
+       if (!f) {
+               Py_INCREF(Py_False);
+               return Py_False;
+       }
+       reiserfs_file_close(f);
+    Py_INCREF(Py_True);
+    return Py_True;
+}
+
+/* reiserfs object */
+
+static PyObject *
+reiser_fs_close (ReiserFs *fs, PyObject *args)
+{
+    if (fs->fs != NULL)
+    {
+        reiserfs_fs_close(fs->fs);
+        file_dal_close(fs->dal);
+               fs->fs = NULL;
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+reiser_fs_open (ReiserFs *fs, PyObject *args)
+{
+    char *name;
+       size_t block_size = DEFAULT_BLOCK_SIZE;
+    dal_t *dal;
+    reiserfs_fs_t *rfs;
+
+    if (!PyArg_ParseTuple(args, "s|i", &name, &block_size))
+        return NULL;
+
+    if (fs->fs != NULL) {
+        PyErr_SetString(PyExc_ValueError, "already have an fs object");
+        return NULL;
+    }
+
+    if (!(dal = file_dal_open(name, block_size, O_RDONLY))) {
+        PyErr_SetString(PyExc_ValueError, "Couldn't create device abstraction");
+        return NULL;    
+    }
+    
+    if (!(rfs = reiserfs_fs_open_fast(dal, dal))) {
+               file_dal_close(dal);
+        PyErr_SetString(PyExc_ValueError, "unable to open file");
+        return NULL;
+    }
+    
+    fs->fs = rfs;
+       fs->dal = dal;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+reiser_fs_open_file (ReiserFs *fs, PyObject *args)
+{
+    char *name;
+    int flags = 0;
+
+    if (!PyArg_ParseTuple(args, "s|i", &name, &flags))
+               return NULL;
+
+    return reiser_file_open(fs, name, flags);
+}
+
+static PyObject *
+reiser_fs_file_exist (ReiserFs *fs, PyObject *args)
+{
+    char * name;
+
+    if (!PyArg_ParseTuple(args, "s", &name))
+        return NULL;
+
+    return reiser_file_exist(fs, name);
+}
+
+static void
+reiser_fs_dealloc (ReiserFs * fs)
+{
+    if (fs->fs != NULL)
+       {
+        reiserfs_fs_close(fs->fs);
+               file_dal_close(fs->dal);
+               fs->fs = NULL;
+       }
+       PyObject_DEL(fs);
+}
+
+static struct PyMethodDef ReiserFsMethods[] = {
+       { "close", (PyCFunction) reiser_fs_close, METH_VARARGS, NULL },
+       { "open", (PyCFunction) reiser_fs_open, METH_VARARGS, NULL },
+       { "open_file", (PyCFunction) reiser_fs_open_file, METH_VARARGS, NULL },
+       { "file_exist", (PyCFunction) reiser_fs_file_exist, METH_VARARGS, NULL },
+       { NULL, NULL, 0, NULL } 
+};
+
+static PyObject *
+reiser_fs_getattr (ReiserFs * fs, char * name)
+{
+        return Py_FindMethod (ReiserFsMethods, (PyObject *) fs, name);
+}
+
+static char ReiserFsType__doc__[] = "This is the reiser filesystem object";
+
+PyTypeObject ReiserFsType = {
+       PyObject_HEAD_INIT(&PyType_Type)
+       0,                              /* ob_size */
+       "ReiserFs",             /* tp_name */
+       sizeof(ReiserFs),               /* tp_size */
+       0,                              /* tp_itemsize */
+       (destructor) reiser_fs_dealloc,         /* tp_dealloc */
+       0,                              /* tp_print */
+       (getattrfunc) reiser_fs_getattr,        /* tp_getattr */
+       0,                              /* tp_setattr */
+       0,                              /* tp_compare */
+       0,                              /* tp_repr */
+       0,                              /* tp_as_number */
+       0,                              /* tp_as_sequence */
+       0,                              /* tp_as_mapping */
+       0,              /* tp_hash */
+       0,              /* tp_call */
+       0,              /* tp_str */
+       0,                              /* tp_getattro */
+       0,                              /* tp_setattro */
+       0,                              /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+       ReiserFsType__doc__,
+       PY_PAD
+};
+
+static PyObject *
+reiser_fs_new(PyObject *o, PyObject *args) 
+{
+    char *name;
+       size_t block_size = DEFAULT_BLOCK_SIZE;
+    ReiserFs *pfs;
+    
+    if (!PyArg_ParseTuple(args, "s|i", &name, &block_size))
+        return NULL;
+    
+    pfs = (ReiserFs *) PyObject_NEW(ReiserFs, &ReiserFsType);
+    if (pfs == NULL)
+        return NULL;
+
+    pfs->fs = NULL;
+    
+    if (!reiser_fs_open(pfs, Py_BuildValue("si", name, block_size)))
+        return NULL;
+    
+    return (PyObject *)pfs;
+}
+
+static struct PyMethodDef ReiserModuleMethods[] = {
+    { "ReiserFs", (PyCFunction) reiser_fs_new, METH_VARARGS},
+    { NULL, NULL, 0}
+};
+
+void init_pyreiser(void) {
+    Py_InitModule("_pyreiser", ReiserModuleMethods);
+}